import { getRandomInt } from "@src/util/misc"
import transporter from "@src/util/email"
import redisClient from "@src/redis/redis"
import { resExample } from "./responseData"
import UserModel from "@src/models/User"
import { Model } from "sequelize"
import { IUser } from "@src/libcommon/modules/user"

/**
 * 发送验证码
 * @param email 邮箱
 * @param type 验证码类型 ('register' | 'update_password')
 */
export const sendCode = async (email: string, type: string = 'register') => {
    try {
        const model = await UserModel()
        const user: Model<IUser, IUser> | null = await model.findOne({
            where: { email }
        })

        // 注册场景：邮箱已存在则不允许发送验证码
        if (type === 'register' && user) {
            throw resExample({
                code: 400,
                message: '该邮箱已被注册',
                success: false,
                data: null
            })
        }

        // 修改密码场景：邮箱不存在则不允许发送验证码
        if (type === 'update_password' && !user) {
            throw resExample({
                code: 400,
                message: '该邮箱未注册',
                success: false,
                data: null
            })
        }

        const code = getRandomInt(6)

        // 发送验证码
        const mailOption = {
            from: '391479141@qq.com', //发件人
            to: email, //收件人
            subject: 'he_chat', //标题
            html: `欢迎使用he_chat,您的邮箱验证码是${code},请不要随意泄露` //正文
        }
        await transporter.sendMail(mailOption)
        console.log('发送的验证码：', code);

        //将验证码存储在 redis 中，设置过期时间为 10 分钟
        const key = `verification_code:${email}:${type}`
        await redisClient.setEx(key, 600, code.toString())
        console.log('验证码已存储到 redis 中，过期时间为 10 分钟！');

    } catch (err) {
        console.error('验证码发送失败', err);
        // 如果是我们主动抛出的错误，直接继续抛出
        if (err.code) {
            throw err
        }
        // 其他错误统一处理为服务器错误
        throw resExample({
            code: 500,
            message: '验证码发送失败',
            data: null,
            success: false
        })
    } finally {
        transporter.close()
    }
}